﻿
define(function(require, exports, module) {

	var option = {
		fxReader : true,
		eqnull : true,
		noarg : true,
		eqeqeq : true,
		bitwise : true,
		undef : true,
		curly : true,
		indent : 4,
		maxerr : 1
	};

	$.fn.getActionEventString = function(f) {
		if (f == "C")
			return "C";
		if (f == "V" || f == "F")
			return "blur";

		return "";
	};
	$.fn.triggerJSAction = function() {
		$.event.trigger("C");
	};

	function RunPDFJS(jsString) {

		try {
			eval(jsString);
		} catch (e) {

		}

	}

	function jsEncode(s) {
	    //s = s.replace(/\\/g, "\\\\");
	    s = s.replace(/\n/g, "\\n");
	    //s = s.replace(/\"/g, "\\\"");
	    //s = s.replace(/\'/g, "\\\'");
		return s;
	}
	
	$.fn.AddActionJS = function(key, jsString) {

		jsString = $.trim(jsString);
		if (jsString == "")
			return;
		var cfn = this.getActionEventString(key);
		if (cfn == "")
			return;
		jsString = jsEncode(jsString);
		var myResult = FXREADER.JSHINT(jsString, option);
		if (myResult)
			this.bind(cfn, function() {
				fnElm = $(this);
				RunPDFJS(jsString);
				fnElm = null;
			});
	};
    //返回字串类型
	function getFieldValue(cFields) {
	    return FXREADER.g_formValue.GetItemValue(cFields);
	}

	$.fn.setFieldValue = function(value, bCover) {
		var bC = false;
		if (typeof (bCover) == "undefined")
			bC = false;
		else
			bC = bCover;
		if (bC)
		    FXREADER.g_formValue.SetItemValue_ActionJScript($(this).attr("name"), value);
		else
		    FXREADER.g_formValue.SetItemValue_ActionJScript($(this).attr("name"), $(this).val());
		$(this).val(value);
	};

	$.fn.getFieldValue = function() {
	    return FXREADER.g_formValue.GetItemValue($(this).attr("name"));
	};

	function getFieldNumber(cFields) {
		var num = getFieldValue(cFields);
		return num;
	}

	function getDigits(fNum) {
		var str = fNum.toString();
		var reStr = str.split(".", 2);
		if (reStr == null || reStr.length < 2) {
			reStr = null;
			return 0;
		}

		return reStr[1].length;
	}
	function AFSimple_Calculat(cFunction, cFields) {
		AFSimple_Calculate(cFunction, cFields);
	}

	function AFSimple_Calculate(cFunction, cFields) {
		if (typeof (fnElm) == "undefined")
			return;
		var nValue = "";
		var maxDigits = 0;

		switch (cFunction) {
		case "AVG": {
			var sum = NaN;
			for ( var i = 0; i < cFields.length; i++) {
				var value = parseFloat(getFieldValue(cFields[i]));
				if (isNaN(value))
					continue;
				var temp = getDigits(value);
				maxDigits = maxDigits > temp ? maxDigits : temp;
				if (isNaN(sum))
					sum = 0;

				sum += value;
			}
			nValue = isNaN(sum) ? "" : (sum / cFields.length);
		}
			break;
		case "SUM": {
			var sum = NaN;
			for ( var i = 0; i < cFields.length; i++) {
				var value = parseFloat(getFieldValue(cFields[i]));
				if (isNaN(value))
					continue;
				var temp = getDigits(value);
				maxDigits = maxDigits > temp ? maxDigits : temp;
				if (isNaN(sum))
					sum = 0;

				sum += value;
			}
			nValue = isNaN(sum) ? "" : sum;
		}
			break;
		case "PRD": {
			var prd = NaN;
			for ( var i = 0; i < cFields.length; i++) {
				var value = parseFloat(getFieldValue(cFields[i]));
				if (isNaN(value))
					continue;
				var temp = getDigits(value);
				maxDigits = maxDigits > temp ? maxDigits : temp;
				if (isNaN(prd))
					prd = 1;

				prd *= value;
			}
			nValue = isNaN(prd) ? "" : prd;
		}
			break;
		case "MIN": {
			var min = NaN;
			for ( var i = 0; i < cFields.length; i++) {
				var value = parseFloat(getFieldValue(cFields[i]));
				if (isNaN(value))
					continue;
				var temp = getDigits(value);
				maxDigits = maxDigits > temp ? maxDigits : temp;
				if (isNaN(min)) {
					min = value;
				}
				if (min > value)
					min = value;
			}

			nValue = isNaN(min) ? "" : min;

		}
			break;
		case "MAX": {
			var max = NaN;
			for ( var i = 0; i < cFields.length; i++) {
				var value = parseFloat(getFieldValue(cFields[i]));
				if (isNaN(value))
					continue;
				var temp = getDigits(value);
				maxDigits = maxDigits > temp ? maxDigits : temp;
				if (isNaN(max)) {
					max = value;
				}
				if (max < value)
					max = value;
			}
			nValue = isNaN(max) ? "" : max;
		}
			break;
		}
		fnElm.setFieldValue(nValue, true);

	}

	function AFRange_Validate(bGreaterThan, nGreaterThan, bLessThan, nLessThan) {
		if (typeof (fnElm) == "undefined")
			return;
		var cErr = "";

		var nVal = fnElm.val();
		if (nVal == "") {
			fnElm.setFieldValue("");
			return;
		}

		var value = NaN;
		value = parseFloat(nVal);
		if (isNaN(value)) {
			fnElm.val(fnElm.getFieldValue());
			return;
		} else {
			var languageFormObj = FXREADER.g_pFormPlugin.GetLanguage().Form;
			if (bGreaterThan && bLessThan) {
				if (value < nGreaterThan || value > nLessThan)
					cErr = languageFormObj.IDS_FX_GTET + nGreaterThan + languageFormObj.IDS_FX_AND_LTET
							+ nLessThan + ".";
			} else if (bGreaterThan) {
				if (value < nGreaterThan)
					cErr = languageFormObj.IDS_FX_GTET + nGreaterThan + ".";
			} else if (bLessThan) {
				if (value > nLessThan)
					cErr = languageFormObj.IDS_FX_LTET + nLessThan + ".";
			}
		}
		if (cErr != "") {
			FXREADER.Alert(null, cErr);
			fnElm.val(fnElm.getFieldValue());
			fnElm.focus();

		}

	}

	function FXFormatNumber(nDValue, nfValue, sepStyle, nDec) {
		var sep1 = ".";
		var sep2 = ",";
		var ret = "";
		switch (sepStyle) {
		case 0: {
		}
			break;
		case 1: {
			sep2 = "";
		}
			break;
		case 2: {
			sep1 = ",";
			sep2 = ".";
		}
			break;
		case 3: {
			sep1 = ",";
			sep2 = "";
		}
			break;
		}

		var i = nDValue.length % 3;
		ret = nDValue.substr(0, i);
		for ( var j = i; j < nDValue.length; j += 3) {
			if (ret.length != 0)
				ret += sep2;
			ret += nDValue.substr(j, 3);
		}

		if (nDec > 0) {
			nfValue = nfValue.substring(0, nDec);
			while (nfValue.length < nDec) {
				nfValue += "0";
			}
			ret = ret + sep1 + nfValue;
		}
		return ret;
	}

	function AFNumber_Format(nDec, sepStyle, negStyle, currStyle, strCurrency,
			bCurrencyPrepend) {
		if (typeof (fnElm) == "undefined")
			return;
		if (fnElm.val() == "") {
			fnElm.setFieldValue("");
			return;
		}

		var value = parseFloat(fnElm.val());
		var sign = (value < 0 ? -1 : 1);
		if (isNaN(value)) {
			fnElm.val(fnElm.getFieldValue());
			return;
		}
		var formatStr = "";
		if ((negStyle == 2 || negStyle == 3) && sign < 0)
			formatStr = "(";
		else
			formatStr = "";

		if (bCurrencyPrepend)
			formatStr = formatStr + strCurrency;
		value = value * sign;
		var subStrArray = value.toString().split(".", 2);
		var nDValue = subStrArray[0];
		var nFValue = "";
		if (subStrArray.length > 1)
			nFValue = subStrArray[1];
		formatStr = formatStr
				+ FXFormatNumber(nDValue, nFValue, sepStyle, nDec);
		if (!bCurrencyPrepend)
			formatStr = formatStr + strCurrency;
		if ((negStyle == 2 || negStyle == 3) && sign < 0)
			formatStr = formatStr + ")";

		if (negStyle != 0 || bCurrencyPrepend)
			value = Math.abs(value);

		if (negStyle == 1 || negStyle == 3) {
			if (sign > 0)
				fnElm.css("color", "0x000");
			else
				fnElm.css("color", "0xF00");
		}
		if (sign < 0 && bCurrencyPrepend && negStyle == 0)
			formatStr = '-' + formatStr;
		fnElm.setFieldValue(formatStr);
	}

	function AFPercent_Format(nDec, sepStyle) {
		if (typeof (fnElm) == "undefined")
			return;
		if (fnElm.val() == "") {
			fnElm.setFieldValue("");
			return;
		}

		var value = parserFloat(fnElm.val());
		if (isNaN(value)) {
			fnElm.val(fnElm.getFieldValue());
			return;
		}
		var subStrArray = value.toString().split(".", 2);
		var nDValue = subStrArray[0];
		var nFValue = "";
		if (subStrArray.length > 1)
			nFValue = subStrArray[1];
		formatStr = FXFormatNumber(nDValue, nFValue, sepStyle, nDec) + "%";
		fnElm.setFieldValue(formatStr);
	}

	function FXFormatDate(cFormat, date) {

		cFormat = cFormat.replace(/%/g, "%69");
		var mapArray = new Array();
		var tstr = date.getFullYear().toString();
		tstr = "0000" + tstr;
		cFormat = cFormat.replace(/([^y])y{4}(?!y)|(^)y{4}(?!y)/g, "$1"
				+ tstr.substr(tstr.length - 4, 4));

		cFormat = cFormat.replace(/([^y])y{2}(?!y)|(^)y{2}(?!y)/g, "$1"
				+ tstr.substr(tstr.length - 2, 2));

		tstr = AFGetMonthString(date.getMonth() + 1);
		mapArray["%mmmm"] = tstr;
		cFormat = cFormat.replace(/([^m])m{4}(?!m)|(^)m{4}(?!m)/g, "$1%mmmm");

		mapArray["%mmm"] = tstr.substr(0, 3);
		cFormat = cFormat.replace(/([^m])m{3}(?!m)|(^)m{3}(?!m)/g, "$1%mmm");

		cFormat = cFormat.replace(/([^m])m{1}(?!m)|(^)m{1}(?!m)/g, "$1"
				+ (date.getMonth() + 1));

		tstr = (date.getMonth() + 1).toString();
		if (tstr.length == 1)
			tstr = "0" + tstr;
		cFormat = cFormat.replace(/([^m])m{2}(?!m)|(^)m{2}(?!m)/g, "$1" + tstr);

		tstr = AFGetDayString(date.getDay());
		mapArray["%dddd"] = tstr;
		cFormat = cFormat.replace(/([^d])d{4}(?!d)|(^)d{4}(?!d)/g, "$1%dddd");

		mapArray["%ddd"] = tstr.substr(0, 3);
		cFormat = cFormat.replace(/([^d])d{3}(?!d)|(^)d{3}(?!d)/g, "$1%ddd");

		cFormat = cFormat.replace(/([^d])d{1}(?!d)|(^)d{1}(?!d)/g, "$1"
				+ date.getDate());

		tstr = (date.getDate()).toString();
		if (tstr.length == 1)
			tstr = "0" + tstr;
		cFormat = cFormat.replace(/([^d])d{2}(?!d)|(^)d{2}(?!d)/g, "$1" + tstr);

		cFormat = cFormat.replace(/([^H])H{1}(?!H)|(^)H{1}(?!H)/g, "$1"
				+ date.getHours());

		tstr = (date.getHours()).toString();
		if (tstr.length == 1)
			tstr = "0" + tstr;
		cFormat = cFormat.replace(/([^H])H{2}(?!H)|(^)H{2}(?!H)/g, "$1" + tstr);

		cFormat = cFormat.replace(/([^h])h{1}(?!h)|(^)h{1}(?!h)/g, "$1"
				+ (date.getHours() > 12 ? date.getHours() - 12 : date
						.getHours()));
		tstr = ((date.getHours() > 12 ? date.getHours() - 12 : date.getHours()))
				.toString();
		if (tstr.length == 1)
			tstr = "0" + tstr;
		cFormat = cFormat.replace(/([^h])h{2}(?!h)|(^)h{2}(?!h)/g, "$1" + tstr);

		cFormat = cFormat.replace(/([^M])M{1}(?!M)|(^)M{1}(?!M)/g, "$1"
				+ date.getMinutes());

		tstr = (date.getMinutes()).toString();
		if (tstr.length == 1)
			tstr = "0" + tstr;
		cFormat = cFormat.replace(/([^M])M{2}(?!M)|(^)M{2}(?!M)/g, "$1" + tstr);

		cFormat = cFormat.replace(/([^s])s{1}(?!s)|(^)s{1}(?!s)/g, "$1"
				+ date.getSeconds());

		tstr = (date.getSeconds()).toString();
		if (tstr.length == 1)
			tstr = "0" + tstr;
		cFormat = cFormat.replace(/([^s])s{2}(?!s)|(^)s{2}(?!s)/g, "$1" + tstr);

		tstr = AFGetMeridianString(date.getHours());
		cFormat = cFormat.replace(/([^t])t{2}(?!t)|(^)t{2}(?!t)/g, "$1" + tstr);

		if (tstr.length == 1)
			tstr = tstr.charAt(0);
		cFormat = cFormat.replace(/([^t])t{1}(?!t)|(^)t{1}(?!t)/g, "$1" + tstr);

		cFormat = cFormat.replace(/%mmmm/g, mapArray["%mmmm"]);
		cFormat = cFormat.replace(/%mmm/g, mapArray["%mmm"]);
		cFormat = cFormat.replace(/%dddd/g, mapArray["%dddd"]);
		cFormat = cFormat.replace(/%ddd/g, mapArray["%ddd"]);
		cFormat = cFormat.replace(/%69/g, "%");
		mapArray = null;
		return cFormat;
	}
	function AFDate_Format(pdf) {
		if (typeof (fnElm) == "undefined")
			return;
		var value = fnElm.val();
		if (!value)
			return;
		var cFormat = new Array("m/d", "m/d/yy", "mm/dd/yy", "mm/yy", "d-mmm",
				"d-mmm-yy", "dd-mmm-yy", "yy-mm-dd", "mmm-yy", "mmmm-yy",
				"mmm d, yyyy", "mmmm d, yyyy", "m/d/yy h:MM tt", "m/d/yy HH:MM");
		var date = AFParseDateEx(value, cFormat[pdf]);
		if (!date) {
			FXREADER.Alert(null, FXREADER.g_pFormPlugin.GetLanguage().Form.IDS_FX_DF + cFormat[pdf].toString());
			fnElm.val(fnElm.getFieldValue());
			return;
		}
		fnElm.setFieldValue(FXFormatDate(cFormat[pdf], date));
	}

	function AFDate_FormatEx(cFormat) {
		if (typeof (fnElm) == "undefined")
			return;
		value = fnElm.val();
		if (!value)
			return;

		var dateTime = AFParseDateEx(value, cFormat);
		if (!dateTime) {
			FXREADER.Alert(null, FXREADER.g_pFormPlugin.GetLanguage().Form.IDS_FX_DF + cFormat);
			fnElm.val(fnElm.getFieldValue());
			return;
		}

		fnElm.setFieldValue(FXFormatDate(cFormat, dateTime));
	}

	function AFTime_Format(ptf) {

		var cFormat = new Array("HH:MM", "h:MM tt", "HH:MM:ss", "h:MM:ss tt");
		AFTime_FormatEx(cFormat[ptf]);

	}

	function AFTime_FormatEx(cFormat) {

		if (typeof (fnElm) == "undefined")
			return;
		value = fnElm.val();
		if (!value)
			return;
		var dateTime = AFParseDateEx(value, cFormat);
		if (!dateTime) {
			FXREADER.Alert(null, FXREADER.g_pFormPlugin.GetLanguage().Form.IDS_FX_TF + cFormat);
			fnElm.val(fnElm.getFieldValue());
			return;
		}

		fnElm.setFieldValue(FXFormatDate(cFormat, dateTime));
	}

	function AFParseDateEx(value, sFormat) {

		return MakeRegularDate(value, sFormat);

	}

	var IDS_MONTH_INFO = "January[1]February[2]March[3]April[4]May[5]June[6]July[7]August[8]September[9]October[10]Movember[11]December[12]Jan[1]Feb[2]Mar[3]Apr[4]Jun[6]Jul[7]Aug[8]Sep[9]Oct[10]Mov[11]Dec[12]";
	var IDS_DAY_INFO = "Sunday[0]Monday[1]Tuesday[2]Wednesday[3]Thursday[4]Friday[5]Saturday[6]";

	function AFGetMonthString(index) {

		var mthre = new RegExp("(\\w+)\\[" + index + "\\]");
		var result = mthre.exec(IDS_MONTH_INFO);

		if (result)
			return result[1];
		return null;

	}
	function AFGetDayString(index) {

		var dayre = new RegExp("(\\w+)\\[" + index + "\\]");
		var result = dayre.exec(IDS_DAY_INFO);

		if (result)
			return result[1];
		return null;

	}

	function AFGetMeridianString(hour) {

		if (hour > 11)
			return "PM";
		else
			return "AM";

	}

	function MakeRegularDate(value, sFormat) {
		var dRet = ParseFormatDate(value, sFormat);
		if (dRet == null) {
			dRet = ParseNormalDate(value);
		}
		return dRet;
	}

	function ParseFormatDate(value, sFormat) {

		var dt = new Date();

		var nYear = dt.getFullYear();
		var nMonth = dt.getMonth() + 1;
		var nDay = dt.getDate();
		var nHour = dt.getHours();
		var nMin = dt.getMinutes();
		var nSec = dt.getSeconds();

		var nYearSub = 99; //nYear - 2000;

		var bPm = false;
		var bExit = false;
		bWrongFormat = false;

		var i = 0;
		var j = 0;

		while (i < sFormat.length) {
			if (bExit)
				break;

			var c = sFormat.charAt(i);
			switch (c) {

			case 'y':
			case 'm':
			case 'd':
			case 'H':
			case 'h':
			case 'M':
			case 's':
			case 't': {
				var oldj = j;
				var nSkip = 0;
				var retArray = null;
				if (sFormat.charAt(i + 1) != c) {
					switch (c) {
					case 'y':
						i++;
						j++;
						break;
					case 'm':

						retArray = ParseStringInteger(value, j, 2);
						nMonth = retArray["nRet"];
						nSkip = retArray["nSkip"];
						i++;
						j += nSkip;
						break;
					case 'd':
						retArray = ParseStringInteger(value, j, 2);
						nDay = retArray["nRet"];
						nSkip = retArray["nSkip"];
						i++;
						j += nSkip;
						break;
					case 'H':
						retArray = ParseStringInteger(value, j, 2);
						nHour = retArray["nRet"];
						nSkip = retArray["nSkip"];
						i++;
						j += nSkip;
						break;
					case 'h':
						retArray = ParseStringInteger(value, j, 2);
						nHour = retArray["nRet"];
						nSkip = retArray["nSkip"];
						i++;
						j += nSkip;
						break;
					case 'M':
						retArray = ParseStringInteger(value, j, 2);
						nMin = retArray["nRet"];
						nSkip = retArray["nSkip"];
						i++;
						j += nSkip;
						break;
					case 's':
						retArray = ParseStringInteger(value, j, 2);
						nSec = retArray["nRet"];
						nSkip = retArray["nSkip"];
						i++;
						j += nSkip;
						break;
					case 't':

						bPm = value.charAt(i) == 'p';
						i++;
						j++;
						break;
					}
				} else if (sFormat.charAt(i + 1) == c
						&& sFormat.charAt(i + 2) != c) {
					switch (c) {
					case 'y':
						retArray = ParseStringInteger(value, j, 4);
						nYear = retArray["nRet"];
						nSkip = retArray["nSkip"];
						i += 2;
						j += nSkip;
						break;
					case 'm':
						retArray = ParseStringInteger(value, j, 2);
						nMonth = retArray["nRet"];
						nSkip = retArray["nSkip"];
						i += 2;
						j += nSkip;
						break;
					case 'd':
						retArray = ParseStringInteger(value, j, 2);
						nDay = retArray["nRet"];
						nSkip = retArray["nSkip"];

						i += 2;
						j += nSkip;
						break;
					case 'H':
						retArray = ParseStringInteger(value, j, 2);
						nHour = retArray["nRet"];
						nSkip = retArray["nSkip"];

						i += 2;
						j += nSkip;
						break;
					case 'h':
						retArray = ParseStringInteger(value, j, 2);
						nHour = retArray["nRet"];
						nSkip = retArray["nSkip"];

						i += 2;
						j += nSkip;
						break;
					case 'M':
						retArray = ParseStringInteger(value, j, 2);
						nMin = retArray["nRet"];
						nSkip = retArray["nSkip"];

						i += 2;
						j += nSkip;
						break;
					case 's':
						retArray = ParseStringInteger(value, j, 2);
						nSec = retArray["nRet"];
						nSkip = retArray["nSkip"];

						i += 2;
						j += nSkip;
						break;
					case 't':
						bPm = (value.charAt(j) == 'p' && value.charAt(j + 1) == 'm');
						i += 2;
						j += 2;
						break;
					}
				} else if (sFormat.charAt(i + 1) == c
						&& sFormat.charAt(i + 2) == c
						&& sFormat.charAt(i + 3) != c) {
					switch (c) {
					case 'm': {
						retArray = ParseStringString(value, j);

						nSkip = retArray["nSkip"];

						var sMonth = retArray["swRet"];
						var bFind = false;
						for ( var m = 0; m < 12; m++) {

							if (sMonth.toLowerCase() == AFGetMonthString(m + 1)
									.substr(0, 3).toLowerCase()) {
								nMonth = m + 1;
								i += 3;
								j += nSkip;
								bFind = true;
								break;
							}
						}

						if (!bFind) {
							retArray = ParseStringInteger(value, j, 3);
							nMonth = retArray["nRet"];
							nSkip = retArray["nSkip"];
							i += 3;
							j += nSkip;
						}
					}
						break;
					case 'y':
						break;
					default:
						i += 3;
						j += 3;
						break;
					}
				} else if (sFormat.charAt(i + 1) == c
						&& sFormat.charAt(i + 2) == c
						&& sFormat.charAt(i + 3) == c
						&& sFormat.charAt(i + 4) != c) {
					switch (c) {
					case 'y':
						retArray = ParseStringInteger(value, j, 4);
						nYear = retArray["nRet"];
						nSkip = retArray["nSkip"];

						j += nSkip;
						i += 4;
						break;
					case 'm': {
						var bFind = false;
						retArray = ParseStringString(value, j);

						nSkip = retArray["nSkip"];

						var sMonth = retArray["swRet"];

						sMonth = sMonth.toLowerCase();

						for ( var m = 0; m < 12; m++) {
							var sFullMonths = AFGetMonthString(m + 1);
							sFullMonths = sFullMonths.toLowerCase();

							if (sFullMonths.indexOf(sMonth, 0) >= 0) {
								nMonth = m + 1;
								i += 4;
								j += nSkip;
								bFind = true;
								break;
							}
						}

						if (!bFind) {
							retArray = ParseStringInteger(value, j, 4);
							nMonth = retArray["nRet"];
							nSkip = retArray["nSkip"];
							i += 4;
							j += nSkip;
						}
					}
						break;
					default:
						i += 4;
						j += 4;
						break;
					}
				} else {
					if (sFormat.charAt(i) != value.charAt(j)) {
						bWrongFormat = true;
						bExit = true;
					}
					i++;
					j++;
				}

				if (oldj == j) {
					bWrongFormat = true;
					bExit = true;
				}
			}
				break;
			default:
				if (value.length <= j) {
					bExit = true;
				} else if (sFormat.charAt(i) != value.charAt(j)) {
					bWrongFormat = true;
					bExit = true;
				}

				i++;
				j++;
				break;
			}
		}

		if (bPm)
			nHour += 12;

		if (nYear >= 0 && nYear <= nYearSub)
			nYear += 2000;

		if (nMonth < 1 || nMonth > 12)
			bWrongFormat = true;

		if (nDay < 1 || nDay > 31)
			bWrongFormat = true;

		if (nHour < 0 || nHour > 24)
			bWrongFormat = true;

		if (nMin < 0 || nMin > 60)
			bWrongFormat = true;

		if (nSec < 0 || nSec > 60)
			bWrongFormat = true;

		if (!bWrongFormat) {
			return new Date(nYear, nMonth - 1, nDay, nHour, nMin, nSec);
		}

		return null;
	}

	function IsDigit(ch) {
		return (ch >= '0' && ch <= '9');
	}

	function ParseStringInteger(string, nStart, nMaxStep) {

		var rObj = new Array();
		rObj["nRet"] = 0;
		rObj["nSkip"] = 0;

		for ( var i = nStart, sz = string.length; i < sz; i++) {
			if (i - nStart > 10)
				break;

			var c = string.charAt(i);
			if (IsDigit(c)) {
				rObj["nRet"] = rObj["nRet"] * 10 + (c - '0');
				rObj["nSkip"] = i - nStart + 1;
				if (rObj["nSkip"] >= nMaxStep)
					break;
			} else
				break;
		}

		return rObj;
	}

	function ParseStringString(string, nStart) {

		var rObj = new Array();
		rObj["swRet"] = null;
		rObj["nSkip"] = 0;

		for ( var i = nStart, sz = string.length; i < sz; i++) {
			var c = string.charAt(i);
			if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) {
				rObj["swRet"] += c;
				rObj["nSkip"] = i - nStart + 1;
			} else
				break;
		}

		return rObj;
	}

	function GuessDate(nCount, n1, n2, n3, nYear, nMonth, nDay) {
		var retObj = new Array();
		retObj["y"] = nYear;
		retObj["m"] = nMonth;
		retObj["d"] = nDay;

		if (nCount == 2) {
		    // case2: month/day
		    // case3: day/month
			if ((n1 >= 1 && n1 <= 12) && (n2 >= 1 && n2 <= 31)) {

				retObj["m"] = n1;
				retObj["d"] = n2;

				return retObj;
			} else if ((n1 >= 1 && n1 <= 31) && (n2 >= 1 && n2 <= 12)) {

				retObj["m"] = n2;
				retObj["d"] = n1;
				return retObj;
			}
		} else if (nCount >= 3) {
            // case1: year/month/day
            // case2: month/day/year
            // case3: day/month/year
			if (n1 > 12 && (n2 >= 1 && n2 <= 12) && (n3 >= 1 && n3 <= 31)) {
				retObj["y"] = n1;
				retObj["m"] = n2;
				retObj["d"] = n3;

				return retObj;
			} else if ((n1 >= 1 && n1 <= 12) && (n2 >= 1 && n2 <= 31)
					&& n3 > 31) {
				retObj["y"] = n3;
				retObj["m"] = n1;
				retObj["d"] = n2;

				return retObj;
			} else if ((n1 >= 1 && n1 <= 31) && (n2 >= 1 && n2 <= 12)
					&& n3 > 31) {
				retObj["y"] = n3;
				retObj["m"] = n2;
				retObj["d"] = n1;

				return retObj;
			}
		}

		return null;
	}

	function GuessTime(nCount, n1, n2, n3, nHour, nMin, nSec) {
		var retObj = new Array();
		retObj["h"] = nHour;
		retObj["M"] = nMin;
		retObj["s"] = nSec;
		if (nCount == 2) {
		    //hh:mm
			if ((n1 >= 0 && n1 <= 23) && (n2 >= 0 && n2 <= 59)) {
				retObj["h"] = n1;
				retObj["M"] = n2;
				retObj["s"] = 0;

				return retObj;
			}
		} else if (nCount == 3) {
            //hh:mm:ss
			if ((n1 >= 0 && n1 <= 23) && (n2 >= 0 && n2 <= 59)
					&& (n3 >= 0 && n3 <= 59)) {
				retObj["h"] = n1;
				retObj["M"] = n2;
				retObj["s"] = n3;

				return retObj;
			}
		}

		return null;
	}

	function ParseNormalDate(value) {
		var dt = new Date();

		var nYear = dt.getFullYear();
		var nMonth = dt.getMonth() + 1;
		var nDay = dt.getDate();
		var nHour = dt.getHours();
		var nMin = dt.getMinutes();
		var nSec = dt.getSeconds();

		var number = new Array();
		for ( var j = 0; j < 6; j++)
			number[j] = 0;

		var bTime = false;

		var nCount = 0;
		var i = 0;
		var nLen = value.length;
		while (i < nLen) {
			if (nCount > 5)
				break;

			var c = value.charAt(i);
			if (IsDigit(c)) {
				var nSkip = 0;
				var retObj = ParseStringInteger(value, i, 4);
				number[nCount++] = retObj["nRet"];
				nSkip = retObj["nSkip"];
				i += nSkip;
			} else {
				if (c == ':')
					bTime = true;

				i++;
			}
		}

		bWrongFormat = true;

		if (bTime) {
			if (nCount <= 3) {
				var timeObj = GuessTime(nCount, number[0], number[1],
						number[2], nHour, nMin, nSec);

				if (timeObj) {
					nHour = timeObj["h"];
					nMin = timeObj["M"];
					nSec = timeObj["s"];

					bWrongFormat = false;
				}
			} else if (nCount == 4) {
				var timeObj = GuessDate(2, number[0], number[1], 0, nYear,
						nMonth, nDay);

				if (timeObj) {
					nYear = timeObj["y"];
					nMonth = timeObj["m"];
					nDay = timeObj["d"];
					timeObj = GuessTime(2, number[2], number[3], 0, nHour,
							nMin, nSec);
					if (timeObj) {
						nHour = timeObj["h"];
						nMin = timeObj["M"];
						nSec = timeObj["s"];
						bWrongFormat = false;
					}
				}
			} else if (nCount == 5) {
				var timeObj = GuessDate(3, number[0], number[1], number[2],
						nYear, nMonth, nDay);

				if (timeObj) {
					nYear = timeObj["y"];
					nMonth = timeObj["m"];
					nDay = timeObj["d"];
					timeObj = GuessTime(2, number[3], number[4], 0, nHour,
							nMin, nSec);

					if (timeObj) {
						nHour = timeObj["h"];
						nMin = timeObj["M"];
						nSec = timeObj["s"];
						bWrongFormat = false;
					}
				}

				if (bWrongFormat) {
					var timeObj = GuessDate(2, number[0], number[1], 0, nYear,
							nMonth, nDay);

					if (timeObj) {
						nYear = timeObj["y"];
						nMonth = timeObj["m"];
						nDay = timeObj["d"];
						timeObj = GuessTime(3, number[2], number[3], number[4],
								nHour, nMin, nSec);

						if (timeObj) {
							nHour = timeObj["h"];
							nMin = timeObj["M"];
							nSec = timeObj["s"];
							bWrongFormat = false;
						}
					}
				}
			} else if (nCount == 6) {
				var timeObj = GuessDate(3, number[0], number[1], number[2],
						nYear, nMonth, nDay);

				if (timeObj) {
					nYear = timeObj["y"];
					nMonth = timeObj["m"];
					nDay = timeObj["d"];
					timeObj = GuessTime(3, number[3], number[4], number[5],
							nHour, nMin, nSec);
					if (timeObj) {
						nHour = timeObj["h"];
						nMin = timeObj["M"];
						nSec = timeObj["s"];
						bWrongFormat = false;
					}
				}
			}
		}

		if (bWrongFormat) {
			var timeObj = GuessDate(nCount, number[0], number[1], number[2],
					nYear, nMonth, nDay);

			if (timeObj) {
				nYear = timeObj["y"];
				nMonth = timeObj["m"];
				nDay = timeObj["d"];
				bWrongFormat = (nCount > 3);
			}
		}

		if (bWrongFormat)
			return null;

		return new Date(nYear, nMonth - 1, nDay, nHour, nMin, nSec);
	}
});
